﻿using System.Collections.Concurrent;
using System.Linq;
using Alchemy.Handlers.WebSocket.hybi00;
using Rebazza.Server.Interfaces;

namespace Rebazza.Server.Entities
{
    public class BaseGameRoom
    {
        private readonly object thisLock = new object();
        public ConcurrentDictionary<IBaseUser, string> Users { get; private set; }

        public bool IsEmpty { get; set; }

        public int RoomNumber { get; private set; }
        
        private int minUserCount;
        private int maxUserCount;

        /// <summary>
        /// Create empty room.
        /// </summary>
        /// <param name="roomNumber"></param>
        public BaseGameRoom(int roomNumber)
        {
            Users = new ConcurrentDictionary<IBaseUser, string>();
            RoomNumber = roomNumber;
            IsEmpty = true;
        }

        /// <summary>
        /// Create filled room.
        /// </summary>
        /// <param name="minUserCount"></param>
        /// <param name="maxUserCount"></param>
        /// <param name="roomNumber"></param>
        public BaseGameRoom(int minUserCount, int maxUserCount, int roomNumber)
        {
            Users = new ConcurrentDictionary<IBaseUser, string>();

            RoomNumber = roomNumber;
            this.minUserCount = minUserCount;
            this.maxUserCount = maxUserCount;
        }

        public void FillRoom(int minUsers, int maxUsers, int roomNumber)
        {
            minUserCount = minUsers;
            maxUserCount = maxUsers;
            RoomNumber = roomNumber;
            IsEmpty = false;
        }

        /// <summary>
        /// Try to add users in game room.
        /// </summary>
        /// <param name="user"></param>
        /// <returns>Return <c>true</c> if user added to game room, else return <c>false</c>.</returns>
        public bool TryAddUser(IBaseUser user)
        {
            lock (thisLock)
            {
                // TODO: Change ClientAddress by id when authenticaton will implemented.
                user.Context.DataFrame = new DataFrame();
                if (Users.Count < maxUserCount && Users.Keys.All(x => x.Context.ClientAddress != user.Context.ClientAddress))
                {
                    return Users.TryAdd(user, string.Empty);
                }

                return false;
            }
        }

        public bool TryRemoveUser(BaseUser user)
        {
            string trash;
            // TODO: save users as value!!! to dictionary
            //user.Context.DataFrame = new DataFrame();
            bool result = Users.TryRemove(user, out trash);
            return result;
        }
    }
}
